Skip to content

fix: match real Perl error returns for tied filehandle I/O#350

Draft
toddr-bot wants to merge 1 commit intocpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-tied-fh-error-returns
Draft

fix: match real Perl error returns for tied filehandle I/O#350
toddr-bot wants to merge 1 commit intocpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-tied-fh-error-returns

Conversation

@toddr-bot
Copy link
Copy Markdown
Collaborator

What

Corrects return values and errno setting for tied filehandle error paths to match real Perl behavior.

Why

syswrite on a read-only handle (or with invalid args) returned 0 instead of undef, making it indistinguishable from "wrote 0 bytes." Similarly, sysread returned 0 instead of undef when the mock was destroyed (EBADF vs EOF). readline and getc on write-only handles warned correctly but didn't set $! = EBADF, diverging from real Perl.

Code that checks defined(syswrite(...)) to detect errors would get false negatives.

How

  • _write_bytes, WRITE, READ: return undef (not 0) on EBADF/EINVAL error paths
  • READLINE, GETC: set $! = EBADF before returning on write-only handles
  • Verified all behaviors against real Perl I/O on the same operations

Testing

  • New t/fh_error_returns.t with 7 subtests covering all corrected paths
  • Updated assertions in t/sysreadwrite_edge_cases.t, t/write_tell.t, t/filehandle_weakref.t, t/filehandle_cleanup.t, t/portability_errno.t to expect undef instead of 0
  • Full test suite passes (95 files, 1593 tests — only pre-existing fh-ref-leak.t failure)

🤖 Generated with Claude Code

syswrite (WRITE) was returning 0 on error conditions where real Perl
returns undef: EBADF on read-only handle, EINVAL for bad length/offset,
and EBADF when mock data is destroyed. Similarly, sysread (READ) returned
0 instead of undef when mock data was gone.

readline (READLINE) and getc (GETC) on write-only handles were missing
$! = EBADF, which real Perl sets alongside the warning.

Changes:
- _write_bytes: return undef (not 0) on EBADF
- WRITE: return undef on all error paths (EBADF, EINVAL)
- READ: return undef (not 0) when mock data is destroyed
- READLINE: set $! = EBADF on write-only handles
- GETC: set $! = EBADF on write-only handles
- New test t/fh_error_returns.t covering all corrected behaviors
- Updated existing tests to expect undef instead of 0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant